package com.songtech.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;


@Configuration
public class DataSourceConfig {

	private Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);
	
	/**
	 * 数据库连接
	 */
	@Value("${spring.datasource.url}")
    private String dbUrl;
    
	/**
	 * 数据库用户名
	 */
    @Value("${spring.datasource.username}")
    private String username;
     
    /**
	 * 数据库pwd
	 */
    @Value("${spring.datasource.password}")
    private String password;
     
    /**
     * 数据库驱动类
     */
    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;
    
    
    /**
     * 初始化连接数
     */
    @Value("${spring.datasource.initialSize}")
    private int initialSize;
    
    
    /**
     * 最小空闲连接
     */
    @Value("${spring.datasource.minIdle}")
    private int minIdle;
    
    /**
     * 最大空闲连接
     */
    @Value("${spring.datasource.maxIdle}")
    private int maxIdle;
    
    /**
     * 
     * 最大活动数
     */
    @Value("${spring.datasource.maxActive}")
    private int maxActive;
    
    /**
     * 
     * 连接被泄露时是否打印
     */
    @Value("${spring.datasource.logAbandoned}")
    private boolean logAbandoned;
    
    /**
     * 
     * 超时等待时间
     */
    @Value("${spring.datasource.maxWait}")
    private int maxWait;
    
    /**
     * 
     * 是否自动回收超时连接
     */
    @Value("${spring.datasource.removeAbandoned}")
    private boolean removeAbandoned;
    
    
    /**
     * 
     * 超时时间
     */
    @Value("${spring.datasource.removeAbandonedTimeout}")
    private int removeAbandonedTimeout;
    
    /**
     * 
     * 在空闲连接回收器线程运行期间休眠的时间值
     */
    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;
    
    /**
     * 
     * 连接在池中保持空闲而不被空闲连接回收时间
     */
    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;
     
    /**
     * 
     * 用来检测连接是否有效的sql
     */
    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;
     
    /**
     * 
     * 申请连接的时候检测
     */
    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;
    
    
    /**
     * druid监控统计用的filter:stat
     */
    @Value("${spring.datasource.filters}")
    private String filters;
	
    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;
	
    
	
    /**
     * 
     * 创建数据源
     * @return
     */
    @Primary  //在同样的DataSource中，首先使用被标注的DataSource
    @Bean(name = "dataSource", initMethod = "init", destroyMethod = "close")
    public DataSource createDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(dbUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        //configuration  
        dataSource.setMinIdle(minIdle);
        //dataSource.setMaxIdle(maxIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setInitialSize(initialSize);
        dataSource.setLogAbandoned(logAbandoned);
        dataSource.setMaxWait(maxWait);
        dataSource.setRemoveAbandoned(removeAbandoned);
        dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setTestOnBorrow(testOnBorrow);
        try {  
        	dataSource.setFilters(filters);
        } catch (SQLException e) {
            logger.error("druid configuration initialization filter", e);
            e.printStackTrace();
        }  
        return dataSource;
    }
    
    /**
     * 
     * 注册druird监控统计servlet
     * @return
     */
    @Bean  
    public ServletRegistrationBean DruidStatViewServlet(){
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
      
        //添加初始化参数：initParams  
        /** 白名单，如果不配置或value为空，则允许所有 */
        servletRegistrationBean.addInitParameter("allow","");
        
        /** 黑名单，与白名单存在相同IP时，优先于白名单 */  
        servletRegistrationBean.addInitParameter("deny","");
        
        /** 用户名 */  
        servletRegistrationBean.addInitParameter("loginUsername","admin");
        
        /** 密码 */  
        servletRegistrationBean.addInitParameter("loginPassword","admin");
        
        /** 禁用页面上的“Reset All”功能 */  
        servletRegistrationBean.addInitParameter("resetEnable","false");
        
        return servletRegistrationBean;
    }
    
    /**
     * 
     * 注册druird监控统计filter
     * @return
     */
    @Bean  
    public FilterRegistrationBean druidStatFilter(){  
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
      
        /** 过滤规则 */  
        filterRegistrationBean.addUrlPatterns("/*");
        /** 忽略资源 */  
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        
        return filterRegistrationBean;
    }    
}
